# coding=utf-8

import os
from typing import Dict, List, Tuple
import xlrd
import xlwt
from xlutils.copy import copy
from parse.sdb_parser import ECU, Signal

from utils.payload import EncodeType, TypeEnum


def parseCarConfig()->Tuple[ECU,ECU,List[EncodeType]]:

    #解释原始文档
    excle:xlrd.book.Book = xlrd.open_workbook("./config/ipcp/carconfig/CarConfig.xls")
    sheet:xlrd.sheet.Sheet =excle.sheet_by_name("baseCarconfig")

    #最新的carconfig
    newCarConfigSheet = excle.sheet_by_name("newCarconfig")

    carconfigLT1000:List[Signal]=[]
    carconfigGT1000:List[Signal]=[]
    newCarconfigLT1000:List[Signal]=[]
    newCarconfigGT1000:List[Signal]=[]

    carconfigEncodeType:Dict[str,str]={}
    enumDefines:List[EncodeType]=[]
    newCarconfigEncodeType:Dict[str,str]={}
    newEnumDefines:List[EncodeType]=[]

    #新增顺序0~999和1000~1255两个carconfig集合
    orderCarconfigLT1000List=[]
    orderCarconfigGT1000List=[]

    #新增0~999和1000~1255两个carconfig集合 存储carconfig信号名称 比如carconfig10
    for index in range(0,1256):
        signalName = "carconfig"+str(index).strip()
        if index < 1000:
            orderCarconfigLT1000List.append(signalName)
        else:
            orderCarconfigGT1000List.append(signalName)
    #end

    for rowIndex in range(1,newCarConfigSheet.nrows):
        carconfigNumber = str(newCarConfigSheet.cell_value(rowIndex, 0)).strip()
        ctype=newCarConfigSheet.cell_type(rowIndex, 0)
        if ctype == 2:
            carconfigNumber = carconfigNumber[:carconfigNumber.find(".")]
        name = str(newCarConfigSheet.cell_value(rowIndex, 1)).strip()
        desc = str(newCarConfigSheet.cell_value(rowIndex, 2)).strip()
        value=str(newCarConfigSheet.cell_value(rowIndex, 3)).strip()#16进制
        ctype=newCarConfigSheet.cell_type(rowIndex, 3)
        if ctype == 2:
            value = value[:value.find(".")]
        valueDesc=str(newCarConfigSheet.cell_value(rowIndex, 4)).strip()

        if carconfigNumber != "":
            signalName = "carconfig"+carconfigNumber
            signal=Signal(signalName,TypeEnum.uint8_t,"","","1","0","",None,"")
            enumName = "CarConfig"+carconfigNumber
            newCarconfigEncodeType[signalName]=enumName
            newEnumDefines.append(EncodeType(enumName,desc,isEnum=True))
            if int(carconfigNumber)<1000:
                if signal not in newCarconfigLT1000:
                    newCarconfigLT1000.append(signal)
            else:
                if signal not in newCarconfigGT1000:
                    newCarconfigGT1000.append(signal)
        enumClass = newEnumDefines[len(newEnumDefines)-1]
        enumClass.addMember("{name} = {value}".format(value=str(int(value,16)),name="_"+value),valueDesc)


    for rowIndex in range(1,sheet.nrows):
        carconfigNumber = str(sheet.cell_value(rowIndex, 0)).strip()
        ctype=sheet.cell_type(rowIndex, 0)
        if ctype == 2:
            carconfigNumber = carconfigNumber[:carconfigNumber.find(".")]
        name = str(sheet.cell_value(rowIndex, 1)).strip()
        desc = str(sheet.cell_value(rowIndex, 2)).strip()
        value=str(sheet.cell_value(rowIndex, 3)).strip()#16进制
        ctype=sheet.cell_type(rowIndex, 3)
        if ctype == 2:
            value = value[:value.find(".")]
        valueDesc=str(sheet.cell_value(rowIndex, 4)).strip()

        if carconfigNumber != "":
            signalName = "carconfig"+carconfigNumber
            signal=Signal(signalName,TypeEnum.uint8_t,"","","1","0","",None,"")
            enumName = "CarConfig"+carconfigNumber
            carconfigEncodeType[signalName]=enumName
            enumDefines.append(EncodeType(enumName,desc,isEnum=True))
            if int(carconfigNumber)<1000:
                if signal not in carconfigLT1000:
                    carconfigLT1000.append(signal)
            else:
                if signal not in carconfigGT1000:
                    carconfigGT1000.append(signal)
        enumClass = enumDefines[len(enumDefines)-1]
        enumClass.addMember("{name} = {value}".format(value=str(int(value,16)),name="_"+value),valueDesc)

    for carconfig in carconfigLT1000:
        encodeName = carconfigEncodeType[carconfig.name]
        for encodeType in enumDefines:
            if encodeType.getTypeName() == encodeName:
                carconfig.textTable=encodeType
                break

    for carconfig in carconfigGT1000:
        encodeName = carconfigEncodeType[carconfig.name]
        for encodeType in enumDefines:
            if encodeType.getTypeName() == encodeName:
                carconfig.textTable=encodeType
                break

    for carconfig in newCarconfigLT1000:
        encodeName = newCarconfigEncodeType[carconfig.name]
        for encodeType in newEnumDefines:
            if encodeType.getTypeName() == encodeName:
                carconfig.textTable=encodeType
                break

    for carconfig in newCarconfigGT1000:
        encodeName = newCarconfigEncodeType[carconfig.name]
        for encodeType in newEnumDefines:
            if encodeType.getTypeName() == encodeName:
                carconfig.textTable=encodeType
                break

    #分析当前输入和正在工作的输入差别
    workingSheet:xlrd.sheet.Sheet =excle.sheet_by_name("working")
    workingLT1000List=[]
    workingGT1000List=[]
    for rowIndex in range(1,workingSheet.nrows):
        ltThousand = str(workingSheet.cell_value(rowIndex, 0)).strip()
        workingLT1000List.append(ltThousand)
        gtThousand = str(workingSheet.cell_value(rowIndex, 1)).strip()
        workingGT1000List.append(gtThousand)


    #<1000的carconfig
    carconfigECU=ECU("CARCONFIG",135)
    #>=1000的carconfig
    carconfigThousandECU=ECU("CARCONFIGTHOUSAND",136)

     #working表（mcu给的数据顺序和内容需要完全一致防止数据窜位）重新进行数据的组合
    # for signalName in workingLT1000List:
    #     signal=Signal(signalName,TypeEnum.uint8_t,"","","1","0","",None,"")
    #     newContains = newCarconfigLT1000.__contains__(signal)
    #     baseContains = carconfigLT1000.__contains__(signal)
    #     if newContains:
    #         signalNewIndex = newCarconfigLT1000.index(signal)
    #         carconfigECU.rxPackage.addSignal(newCarconfigLT1000[signalNewIndex])
    #     elif baseContains:
    #         signalBaseIndex = carconfigLT1000.index(signal)
    #         carconfigECU.rxPackage.addSignal(carconfigLT1000[signalBaseIndex])
    #
    #
    # for signalName in workingGT1000List:
    #     signal=Signal(signalName,TypeEnum.uint8_t,"","","1","0","",None,"")
    #     newContains = newCarconfigGT1000.__contains__(signal)
    #     baseContains = carconfigGT1000.__contains__(signal)
    #     if newContains:
    #         signalNewIndex = newCarconfigGT1000.index(signal)
    #         carconfigThousandECU.rxPackage.addSignal(newCarconfigGT1000[signalNewIndex])
    #     elif baseContains:
    #         signalBaseIndex = carconfigGT1000.index(signal)
    #         carconfigThousandECU.rxPackage.addSignal(carconfigGT1000[signalBaseIndex])

    #signal重新填充carconfig顺序0~999集合 carconfig无enum项默认填充0
    for signalName in orderCarconfigLT1000List:
        signal=Signal(signalName,TypeEnum.uint8_t,"","","1","0","",None,"")
        newContains = newCarconfigLT1000.__contains__(signal)
        baseContains = carconfigLT1000.__contains__(signal)
        workingContains = workingLT1000List.__contains__(signalName)
        if workingContains:
            if newContains:
                signalNewIndex = newCarconfigLT1000.index(signal)
                carconfigECU.rxPackage.addSignal(newCarconfigLT1000[signalNewIndex])
            elif baseContains:
                signalBaseIndex = carconfigLT1000.index(signal)
                carconfigECU.rxPackage.addSignal(carconfigLT1000[signalBaseIndex])
        else:
            newSignal = signal
            value = str("0").strip()
            name = str("0").strip()
            encode = EncodeType(signalName,"default",isEnum=True)
            encode.addMember("{name} = {value}".format(value=str(int(value,16)),name="_"+value),"default")
            newSignal.textTable=encode
            carconfigECU.rxPackage.addSignal(newSignal)

    #signal重新填充carconfig顺序1000~1255集合 carconfig无enum项默认填充0
    for signalName in orderCarconfigGT1000List:
        signal=Signal(signalName,TypeEnum.uint8_t,"","","1","0","",None,"")
        newContains = newCarconfigGT1000.__contains__(signal)
        baseContains = carconfigGT1000.__contains__(signal)
        workingContains = workingGT1000List.__contains__(signalName)
        if workingContains:
            if newContains:
                signalNewIndex = newCarconfigGT1000.index(signal)
                carconfigThousandECU.rxPackage.addSignal(newCarconfigGT1000[signalNewIndex])
            elif baseContains:
                signalBaseIndex = carconfigGT1000.index(signal)
                carconfigThousandECU.rxPackage.addSignal(carconfigGT1000[signalBaseIndex])
        else:
            newSignal = signal
            value = str("0").strip()
            name = str("0").strip()
            encode = EncodeType(signalName,"default",isEnum=True)
            encode.addMember("{name} = {value}".format(value=str(int(value,16)),name="_"+value),"default")
            newSignal.textTable=encode
            carconfigThousandECU.rxPackage.addSignal(newSignal)


    #将最新的carconfig写入excle的working目录

    return (carconfigECU,carconfigThousandECU,enumDefines)




